package com.xianyun.book.gatewayimpl;

import com.alibaba.cola.exception.Assert;
import com.xianyun.book.common.core.event.DomainEventPublisher;
import com.xianyun.book.convertor.BookConvertor;
import com.xianyun.book.domain.book.Book;
import com.xianyun.book.domain.book.BookStatus;
import com.xianyun.book.domain.book.BookType;
import com.xianyun.book.domain.gateway.BookGateway;
import com.xianyun.book.domain.order.SalesOrder;
import com.xianyun.book.dto.domainevent.BookTransactionEvent;
import com.xianyun.book.gatewayimpl.database.BookMapper;
import com.xianyun.book.gatewayimpl.database.BookTypeMapper;
import com.xianyun.book.gatewayimpl.database.dataobject.BookDO;
import com.xianyun.book.gatewayimpl.database.dataobject.BookTypeDO;
import com.xianyun.book.gatewayimpl.elasticsearch.repository.BookEsRepository;
import com.xianyun.book.gatewayimpl.handle.IsbnQueryGatewayHandle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;

/**
 * @author ytt
 */
@Slf4j
@Component
public class BookGatewayImpl implements BookGateway {

    @Resource
    private IsbnQueryGatewayHandle queryGatewayHandle;

    @Resource
    private BookMapper bookMapper;

    @Resource
    private BookTypeMapper typeMapper;

    @Resource
    private BookEsRepository bookRepository;

    @Resource
    private DomainEventPublisher domainEventPublisher;


    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void updateBook(Book book) {
        BookDO updateBook = BookConvertor.toDateObject(book);
        bookMapper.update(updateBook);
    }

    @Override
    public void refreshBook(SalesOrder salesOrder) {
        BookTransactionEvent event = new BookTransactionEvent();
        event.setBookFineness(salesOrder.getFinenessType());
        event.setUserSecurity(salesOrder.getUserSecurity());
        event.setBuyer(salesOrder.isBuyer());
        event.setIsbn(salesOrder.getIsbn());
        if (salesOrder.isBuyer()){
            event.setBookNumber(salesOrder.getBuyNumber());
        } else {
            event.setBookNumber(salesOrder.getSellNumber());
        }
        domainEventPublisher.publish(event);
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void save(Book book) {
        book.setBookId(UUID.randomUUID().toString());
        book.setBookStatus(BookStatus.PRE_SALE);
        BookDO saveBook = BookConvertor.toDateObject(book);
        saveBook.setAddTime(new Date());
        saveBook.setSalesVolume(0);
        bookMapper.create(saveBook);
        book.getBookTypes().forEach(bookType -> {
            bookMapper.saveBookTypeAssociate(saveBook.getId(), bookType.getId());
        });
        log.info("新书上架: 书名:{},ISBN:{},书籍状态:{} --上架成功",book.getBookName(),book.getIsbn(),book.getBookStatus().getMessage());
    }

    @Override
    public List<String> bookSearchCompletion(String searchKey) {
       return bookRepository.searchBookSuggest(searchKey);
    }

    @Override
    public Book saveOrQueryBookByIsbn(String isbn) {
        return queryGatewayHandle.execute(isbn);
    }


    @Override
    public List<BookType> conversionTypeList(List<String> typeList) {
        Assert.notEmpty(typeList,"书籍类型不能为空");
        List<BookType> resultBookType = new ArrayList<>(10);
        typeList.forEach(typeName ->{
            BookTypeDO bookTypeResult = typeMapper.selectBookTypeByTypeName(typeName);
            if (null != bookTypeResult){
                BookType bookType = new BookType();
                BeanUtils.copyProperties(bookTypeResult,bookType);
                resultBookType.add(bookType);
            }
        });
        if (resultBookType.isEmpty()){
            for (String bookType : typeList){
                BookTypeDO saveType = new BookTypeDO();
                saveType.setTypeName(bookType);
                saveType.setIsRootNode(false);
                saveType.setCountNumber(1);
                typeMapper.save(saveType);
            }
            return  conversionTypeList(typeList);
        }
        return resultBookType;
    }
}
